import uuid
from datetime import datetime, timedelta

# 存储验证码的内存数据库，实际生产环境可替换为Redis
captcha_store = {}

# 短信验证码的内存数据库，实际生产环境可替换为Redis
sms_code_store = {}


def generate_captcha_id() -> str:
    """生成唯一的验证码ID"""
    return str(uuid.uuid4())


def store_captcha(code: str, expiration_minutes: int = 5) -> str:
    """
    存储验证码并设置过期时间
    
    参数:
        code: 验证码字符串
        expiration_minutes: 过期时间(分钟)
        
    返回:
        验证码ID
    """
    captcha_id = generate_captcha_id()
    expiration_time = datetime.now() + timedelta(minutes=expiration_minutes)
    captcha_store[captcha_id] = {
        "code": code.lower(),  # 转为小写，不区分大小写验证
        "expires_at": expiration_time
    }
    return captcha_id


def verify_captcha(captcha_id: str, user_input: str) -> bool:
    """
    验证验证码是否正确
    
    参数:
        captcha_id: 验证码ID
        user_input: 用户输入的验证码
        
    返回:
        验证结果(True/False)
    """
    # 清理过期的验证码
    now = datetime.now()
    expired_ids = [
        cid for cid, data in captcha_store.items() if data["expires_at"] < now
    ]
    for cid in expired_ids:
        del captcha_store[cid]

    # 验证验证码
    if captcha_id not in captcha_store:
        return False

    stored_code = captcha_store[captcha_id]["code"]
    # 验证成功后删除验证码，防止重复使用
    del captcha_store[captcha_id]

    return user_input.lower() == stored_code


def store_sms_code(mobile: str, code: str, expiration_minutes: int = 5) -> str:
    """
    存储短信验证码并设置过期时间
    
    参数:
        code: 验证码字符串
        expiration_minutes: 过期时间(分钟)
        
    返回:
        验证码ID
    """
    expiration_time = datetime.now() + timedelta(minutes=expiration_minutes)
    sms_code_store[mobile] = {
        "code": code.lower(),  # 转为小写，不区分大小写验证
        "expires_at": expiration_time
    }
    return code


def verify_sms_code(
    mobile: str,
    code: str,
) -> bool:
    """
    校验短信验证码
    
    参数:
        mobile: 手机号
        code: 用户输入的验证码
        
    返回:
        验证结果(True/False)
    """
    # 清理过期的验证码
    now = datetime.now()
    expired_ids = [
        cid for cid, data in sms_code_store.items() if data["expires_at"] < now
    ]
    for cid in expired_ids:
        del sms_code_store[cid]

    # 验证验证码
    if mobile not in sms_code_store:
        return False

    sms_code = sms_code_store[mobile]["code"]
    # 验证成功后删除验证码，防止重复使用
    del sms_code_store[mobile]

    return sms_code.lower() == code
